
MusicManager
------------
Base address of global MusicManager object: 0x00565390


Offset 	Size 	Description
------ 	---- 	-----------
0x0	4	DirectSoundBuffer *DSBuffer
0x4	4	MMRESULT timerID
0x8	4	int boolPlaying
0xC	4	
0x10	4	int volumeIndex (0 = Full, 5 = Quiet)
0x14	4	int pauseLockCount (Non zero is music is paused - game paused)
0x18	4	int boolPlayMusic (Needs more than a mem edit to work)
0x1C	4	char *headerData
0x20	4	HANDLE hClmFile
0x24	4	totalFileHeaderSize
0x28	4*26	int songIndex[26]
 0x28	 4	 0. "EDEN11"
 0x2C	 4	 1. "EDEN21"
 0x30	 4	 2. "EDEN22"
 0x34	 4	 3. "EDEN31"
 0x38	 4	 4. "EDEN32"
 0x3C	 4	 5. "EDEN33"
 0x40	 4	 6. "EP41"
 0x44	 4	 7. "EP42"
 0x48	 4	 8. "EP43"
 0x4C	 4	 9. "EP51"
 0x50	 4	 10. "EP52"
 0x54	 4	 11. "EP61"
 0x58	 4	 12. "EP62"
 0x5C	 4	 13. "EP63"
 0x60	 4	 14. "PLYMTH11"
 0x64	 4	 15. "PLYMTH12"
 0x68	 4	 16. "PLYMTH21"
 0x6C	 4	 17. "PLYMTH22"
 0x70	 4	 18. "PLYMTH31"
 0x74	 4	 19. "PLYMTH32"
 0x78	 4	 20. "PLYMTH33"
 0x7C	 4	 21. "STATIC01"
 0x80	 4	 22. "STATIC02"
 0x84	 4	 23. "STATIC03"
 0x88	 4	 24. "STATIC04"
 0x8C	 4	 25. "STATIC05"
0x90	4	CRITICAL_SECTION timerCriticalSection (Controls access to timerID)

0xA8	4	int bool???
0xAC	4	CRITICAL_SECTION criticalSection (Controls access to 0xA8)

0xC4	4	int numPlaylistEntries
0xC8	4	int repeatStartIndex
0xCC	4	enum SongIds *playList
0xD0	4	int currentPlayingSongIndex (Index into the playList)
0xD4	4	int boolStartedPlaying (Has playback begun at the first song yet)
0xD8	4	int currentSongFileIndex (Index into the file index table)
0xDC	4	int currentSongPosition (Number of bytes into the wav data)




SoundBufferFilling
------------------
A timer callback function at address: 0x00450CF0 is used to fill the music sound buffer with data from the CLM file. This also handles moving from one song to the next.


A potentially good place to hook the music filling callback function is at address: 0x00450DC0 and 0x00450E58. At this point, all checking to see if music should be played is completed, and the buffer offset to start the fill at has been selected. The total music buffer size is 0x10000, and the fills occur in either the first 0x8000 bytes or the last 0x8000 bytes. For a hook at the first address, the write offset for the fill is in ECX, and for a hook at the second address, the write offset is 0. (First time fill).

These address are where the section of the current song is prepared for play, or the song is switched to a new one if the old one was finished (or the first song is playing for the first time). The sound buffer must be locked, filled, and unlocked during this section of code.

A potentially good return point is at address: 0x00450F59. By this point, the sound buffer should have been filled and unlocked. At this address, state variables are checked to see if the buffer needs to be set playing. State is updated and the critical section is left at this point. There are no expected values to be held in trashable registers at this return point. All needed values are reloaded from memory.



Additional notes:
The Critical Section objects are initialized during program startup, so they can be used to guard entry to the overwritten code during the overwrite process. The DLL is loaded before further sound initialization, so the hook can be properly installed in DllMain. The sound initialization is completed before calling InitProc. This includes creating the sound buffers and setting up the timer callback. After InitProc runs, the sound is "Unpaused", so playback can begin the next time the timer callback function is executed.

